#include "Tool.h"

#include <vector>
#include "UpLeftFirstTooth.h"
#include "UpLeftSecondTooth.h"
#include "UpLeftThirdTooth.h"
#include "UpRightFirstTooth.h"
#include "UpRightSecondTooth.h"
#include "UpRightThirdTooth.h"
#include "DownLeftFirstTooth.h"
#include "DownLeftSecondTooth.h"
#include "DownLeftThirdTooth.h"
#include "DownRightFirstTooth.h"
#include "DownRightSecondTooth.h"
#include "DownRightThirdTooth.h"

Tool::Tool(void)
{
}


Tool::~Tool(void)
{
}

Tool::Tool(std::vector<BaseTooth*> pTwTooth){
	twTooth = pTwTooth;
}

CCRect Tool::rect()
{
    CCSize s = getTexture()->getContentSize();
    return CCRectMake(-s.width / 2, -s.height / 2, s.width, s.height);
}


bool Tool::initWithTexture(CCTexture2D* aTexture)
{
    if( CCSprite::initWithTexture(aTexture) ) 
    {
        t_state = kToolStateUngrabbed;
    }
    
    return true;
}

void Tool::onEnter()
{
    CCDirector* pDirector = CCDirector::sharedDirector();
    pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
    CCSprite::onEnter();
}

void Tool::onExit()
{
    CCDirector* pDirector = CCDirector::sharedDirector();
    pDirector->getTouchDispatcher()->removeDelegate(this);
    CCSprite::onExit();
}    

bool Tool::containsTouchLocation(CCTouch* touch)
{
    return rect().containsPoint(convertTouchToNodeSpaceAR(touch));
}

bool Tool::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
    if (t_state != kToolStateUngrabbed) return false;
    if ( !containsTouchLocation(touch) ) return false;
    
    t_state = kToolStateGrabbed;
    return true;
}

void Tool::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
    // If it weren't for the TouchDispatcher, you would need to keep a reference
    // to the touch from touchBegan and check that the current touch is the same
    // as that one.
    // Actually, it would be even more complicated since in the Cocos dispatcher
    // you get CCSets instead of 1 UITouch, so you'd need to loop through the set
    // in each touchXXX method.
	 CCPoint touchPoint = touch->getLocation();
	CCLOG("CCPoint: %s %f %s %f \n", "x:", touchPoint.x, "y:", touchPoint.y);
    
    CCAssert(t_state == kToolStateGrabbed, "Tool - Unexpected state!");    

    setPosition( ccp(touchPoint.x, touchPoint.y) );

	//±È¿˙—¿≥›
	for(std::vector<BaseTooth*>::size_type ix=0; ix!=twTooth.size(); ++ix){
		//CCLOG("BaseTooth: %s %i \n", "ix:", ix);
		//≤Èø¥ «‘⁄ƒƒø≈—¿≥›
		if(twTooth[ix]->checkToolInWhichTooth(touchPoint.x - relativeX, touchPoint.y - relativeY)){
			//CCLOG("checkToolInWhichTooth: %s \n", "true");
			currentTooth = ix;
			for(std::vector<BaseBadPoint*>::size_type jx=0; jx!=twTooth[ix]->badteeth.size(); ++jx){
				//CCLOG("BaseBadPoint: %s %i \n", "jx:", jx);
				CCLOG("BaseBadPoint: %u == %u \n", twTooth[ix]->badteeth[jx]->kind, this->fixKind);
				//»Áπ˚π§æﬂŒ«∫œ£¨æÕ–ﬁ∏¥
				if(twTooth[ix]->badteeth[jx]->kind == this->fixKind){
                    currentBadTooth = jx;
					//CCLOG("fixBadTooth: %s \n", "true");
                    if(twTooth[ix]->badteeth[jx]->kind == BaseBadPoint::BLACK){
                        if(twTooth[ix]->badteeth[jx]->empty == false){
                            twTooth[ix]->toothSprite->setOpacity(0);
                            twTooth[ix]->badteeth[jx]->fixBadTooth();
                        }
                    }else if(twTooth[ix]->badteeth[jx]->kind == BaseBadPoint::EMPTY){
                        if(twTooth[ix]->badteeth[jx]->empty == true){
                            twTooth[ix]->toothSprite->setOpacity(100);
                        }
                    }else{
                        twTooth[ix]->badteeth[jx]->fixBadTooth();
                    }
				}
			}
		}
	}

	for(std::vector<BaseTooth*>::size_type ix=0; ix!=twTooth.size(); ++ix){
		if(!twTooth[ix]->checkToolInWhichTooth(touchPoint.x - relativeX, touchPoint.y - relativeY)){
			for(std::vector<BaseBadPoint*>::size_type jx=0; jx!=twTooth[ix]->badteeth.size(); ++jx){
				if(twTooth[ix]->badteeth[jx]->kind == BaseBadPoint::EMPTY && twTooth[ix]->badteeth[jx]->empty == true){
                    twTooth[ix]->toothSprite->setOpacity(0);
                }else
                    twTooth[ix]->badteeth[jx]->stopFix();
			}
		}
	}
}

void Tool::ccTouchEnded(CCTouch* touch, CCEvent* event)
{
    if(twTooth[currentTooth]->badteeth.size() > currentBadTooth){
        if(this->fixKind == twTooth[currentTooth]->badteeth[currentBadTooth]->kind){
            if(twTooth[currentTooth]->badteeth[currentBadTooth]->kind == BaseBadPoint::BLACK){
                twTooth[currentTooth]->badteeth[currentBadTooth]->remove(0);
            }
            else if(twTooth[currentTooth]->badteeth[currentBadTooth]->kind == BaseBadPoint::EMPTY){
                if(twTooth[currentTooth]->badteeth[currentBadTooth]->empty == true){
                    twTooth[currentTooth]->badteeth[currentBadTooth]->empty = false;
                    twTooth[currentTooth]->badteeth[currentBadTooth]->finishFixed = true;
                    twTooth[currentTooth]->toothSprite->setOpacity(255);
                    
                }
            }
            else
                twTooth[currentTooth]->badteeth[currentBadTooth]->stopFix();
        }
        
    }
    
    //检查游戏是否结束
    bool finished = true;
    for(std::vector<BaseTooth*>::size_type ix=0; ix!=twTooth.size(); ++ix){
			for(std::vector<BaseBadPoint*>::size_type jx=0; jx!=twTooth[ix]->badteeth.size(); ++jx){
                    finished &= twTooth[ix]->badteeth[jx]->finishFixed;
                CCLOG("twTooth[ix]->badteeth[jx]->finishFixed : %i ", twTooth[ix]->badteeth[jx]->finishFixed);
			}
	}
    
    if(finished)
        CCLOG("Finished The Game!");
    else
        CCLOG("Come On!");

	setPosition(ccp(touchEndedX,touchEndedY));
    t_state = kToolStateUngrabbed;
}

CCObject* Tool::copyWithZone(CCZone *pZone)
{
    this->retain();
    return this;
}

void Tool::touchDelegateRetain()
{
    this->retain();
}

void Tool::touchDelegateRelease()
{
    this->release();
}
